﻿using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace ScormModel
{
    [XmlRoot("manifest")]
    [Serializable()]
    public class ImsManifest
    {
        private string _templateCourse;
        private string _identifier = "";
        private string _version = "";
        private string _schemaLocation = "";
        private Metadata _metadata;
        private Organizations _organizations;
        private Resources _resources;
        private SequencingCollection _sequencingCollection;

        private Hashtable listTitleHistory = new Hashtable();
        private Hashtable listModuleObjective = new Hashtable();
        private List<LinkModuleObjective> listObjectiveLog = new List<LinkModuleObjective>();
        
        [NonSerialized]
        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces _xmlNameSpace = new XmlSerializerNamespaces();

        [XmlIgnoreAttribute]
        public List<LinkModuleObjective> ListObjectiveLog
        {
            get { return this.listObjectiveLog; }
        }
        [XmlIgnoreAttribute]
        public Hashtable ListModuleObjective
        {
            get { return this.listModuleObjective; }
        }
        [XmlIgnoreAttribute]
        public Hashtable ListTitleHistory
        {
            get { return this.listTitleHistory; }
        }
        [XmlIgnoreAttribute]
        public XmlSerializerNamespaces xmlNameSpace
        {
            get { return this._xmlNameSpace; }
            set { this._xmlNameSpace = value; }
        }

        [XmlAttribute("identifier")]
        public string Identifier
        {
            get { return this._identifier; }
            set { this._identifier = value; }
        }
       
       
        [XmlAttribute("version")]
        public string Version
        {
            get { return this._version; }
            set { this._version = value; }
        }
       

        [XmlAttribute(Namespace = XmlSchema.InstanceNamespace)]
        public string SchemaLocation
        {
            get { return this._schemaLocation; }
            set { this._schemaLocation = value; }
        }

        [XmlElement("metadata")]
        public Metadata ManifestMetadata
        {
            get { return this._metadata; }
            set { this._metadata = value; }
        }

        [XmlElement("organizations")]
        public Organizations ManifestOrganizations
        {
            get { return this._organizations; }
            set { this._organizations = value; }
        }

        [XmlElement("resources")]
        public Resources Resources
        {
            get { return this._resources; }
            set { this._resources = value; }
        }
        [XmlElement("sequencingCollection")]
        public SequencingCollection SequencingCollection
        {
            get { return this._sequencingCollection; }
            set { this._sequencingCollection = value; }
        }
        public void Clear()
        {
            this._organizations.ListOrganization.Clear();
            this._resources.ListResource.Clear();
        }
        public ImsManifest buildFromXmlTemplate(XmlNode template)
        {
            _organizations = new Organizations();
            _resources = new Resources();
            XmlNodeList childList = template.ChildNodes;
            for (int i = 0; i < childList.Count; i++)
            {
                if (childList[i].Name == "metadata")
                {
                    _metadata = new Metadata();
                    _metadata.MetadataContent = childList[i];
                    _metadata.buildMetadata();
                }
                else if (childList[i].Name == "organizations")
                {
                    _organizations.OrganizationsContent = childList[i];
                    _organizations.buildOrganizations(_templateCourse);

                }
                else if (childList[i].Name == "resources")
                {
                    _resources.ResourcesContent = childList[i];
                    _resources.buildResources();
                }

            }
            return this;
        }
        public TreeViewItem createManifestTreeViewItem()
        {
            //TreeViewItem rootItem = null;
            //rootItem = TreeUtil.GetTreeView("North America", "usa.png");
            //rootItem.Items.Add(_organizations.createOrganizationsTreeViewItem());
            //return rootItem;
            return _organizations.createOrganizationsTreeViewItem();
        }
        public TreeViewItem initManifest()
        {
            return _organizations.initCustomCourse();
        }
        [XmlIgnoreAttribute]
        public string TemplateCourse
        {
            get { return this._templateCourse; }
            set { this._templateCourse = value; }
        }
        public Organization findOrganizationByTitle(string title)
        {
            for (int i = 0; i < _organizations.ListOrganization.Count; i++)
            {
                Organization org = _organizations.ListOrganization[i];
                if (org.Title == title)
                    return org;
                else
                    continue;
            }
            return null;
        }
        public Item findItem(string title)
        {
            for (int i = 0; i < _organizations.ListOrganization.Count; i++)
            {
                Organization org = _organizations.ListOrganization[i];
                Item item = findItemByTitle(org.ListItem,title);
                if (item != null)
                    return item;
            }
            return null;
        }
        public Item findItemByTitle(List<Item> listItem,string title)
        {
            for (int i = 0; i < listItem.Count; i++)
            {
                Item item = listItem[i];
                if (item.Title == title)
                    return item;
                else if (item.ListChildItem.Count > 0)
                    for (int j = 0; j < item.ListChildItem.Count; j++)
                    {
                        listItem.Add(item.ListChildItem[j]);
                    }
                else
                    continue;
            }
                return null;
        }
        public string findTypeOfItem(string title)
        {
            string type = "";
            Organization org = findOrganizationByTitle(title);
            if (org != null)
                type = org.Type;
            Item item = findItem(title);
            if (item != null)
                type = item.ItemType;
            return type;
        }
        public Organization findOrganizationByName(string title)
        {
            Organization org = findOrganizationByTitle(title);
            return org;
        }
        public Item findItemByName(string title)
        {
            Item item = findItem(title);
            return item;
        }
        public string getNameOfTreeViewItem(TreeViewItem selectedItem)
        {
            StackPanel sp = null;
            Label setectItemLabel = null;
            sp = (StackPanel)selectedItem.Header;
            foreach (var child in sp.Children)
            {
                if (child.GetType().ToString() == "System.Windows.Controls.Label")
                    setectItemLabel = (Label)child;

            }
            if (setectItemLabel != null)
                return (setectItemLabel.Content).ToString();
            else
                return "Undefine";
        }
        public Boolean addItem(Item parent, Item child, string template)
        {
            Boolean result = false;
            switch (template)
            {
                case "None":
                    result = addItemForNoneTemplate(parent,child);
                    break;
                case "Linear":
                    break;
                case "Linear_Choice":
                    break;
                case "Linear_Controls":
                    break;
                case "Constrained_Choice":
                    break;
                case "Competency":
                    break;
                case "KnowledgePaced":
                    break;
                case "KnowledgePaced_Reuse":
                    break;
                case "Remediation":
                    break;
                default:
                    break;
            }
            return result;
        }
        public Boolean addItemForNoneTemplate(Item parent, Item child)
        {
            Boolean result = false;
            try{
                if (parent.ItemType == "COURSE")
                {
                    Item examItem = parent.ListChildItem[parent.ListChildItem.Count - 1];
                    parent.ListChildItem.RemoveAt(parent.ListChildItem.Count - 1);
                    parent.ListChildItem.Add(child);
                    parent.ListChildItem.Add(examItem);
                }
                else if (parent.ItemType == "MODULE")
                {
                    parent.ListChildItem.Add(child);
                }
                else if (parent.ItemType == "EXAM")
                {
                    parent.ListChildItem.Add(child);
                }
               result = true;
            }catch(Exception e)
            {
                result = false;
            }   
            return result;
        }
        public Boolean addModuleForNoneTemplate(Organization parent, Item child)
        {
            Boolean result = false;
            try
            {
                Item examItem = parent.ListItem[parent.ListItem.Count - 1];
                parent.ListItem.RemoveAt(parent.ListItem.Count - 1);
                parent.ListItem.Add(child);
                parent.ListItem.Add(examItem);
                result = true;
            }
            catch (Exception e)
            {
                result = false;
            }
            return result;
        }
        public void clearResources()
        {
            this._resources.ListResource = new List<Resource>();
        }
    }
}
 